﻿using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace personalplaner.business
{
    public interface IItem
    {
        string Name { get; set; }

        int ID { get; set; }
    }

    /// <summary>
    /// Base class for all buisness objects
    /// </summary>
	public class ItemBase : IItem, INotifyPropertyChanged, /*IFocusMover,*/ IDataErrorInfo
    {
		#region IDataErrorInfo Members

		/// <summary>
		/// Gets an error message indicating what is wrong with this object.
		/// </summary>
		/// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
		public string Error { get; private set; }

		/// <summary>
		/// Gets the error message for the property with the given name.
		/// </summary>
		/// <returns>The error message for the property. The default is an empty string ("").</returns>
		public string this[string property]
		{
			get
			{
				string msg = !string.IsNullOrEmpty(property) ? IsPropertyValid(property) : string.Empty;
				if (string.IsNullOrEmpty(msg))
				{
					this.Error = null;
				}
				else
				{
					this.Error = property;  //Keep track of the most recently validated property that is invalid.
				}
				return msg;
			}
		}

		/// <summary>
		/// Determines whether the specified property is valid.
		/// </summary>
		/// <param name="property">The name of the property.</param>
		/// <returns>if not valid the error message, otherwise null.</returns>
		protected virtual string IsPropertyValid(string property)
		{
			return null;
		}

		List<string> validateProperties;
		private void FillValidateProperties()
		{

			if (validateProperties != null)
				return;


			//get all properties of the instance (properties of child and base class)
			var properties = (from p in this.GetType().GetProperties()
							  where p.DeclaringType != typeof(ItemBase) && p.Name != "DataValue" && p.Name != "Id"
							  select p).ToList();

			validateProperties = (from ia in properties
								  orderby ia.Name
								  select ia.Name).ToList();

			//List<AttributeNameOrder> listItemAttribute = new List<AttributeNameOrder>();
			//var orderPosition = double.MaxValue;

			//foreach (var propertyInfo in properties)
			//{
			//    var customAttributes = propertyInfo.GetCustomAttributes(true).OfType<ItemFocusOrderAttribute>().FirstOrDefault();
			//    if (customAttributes != null)
			//    {
			//        listItemAttribute.Add(new AttributeNameOrder() { Name = propertyInfo.Name, Order = customAttributes.Order });
			//    }
			//    else
			//    {
			//        listItemAttribute.Add(new AttributeNameOrder() { Name = propertyInfo.Name, Order = orderPosition-- });
			//    }
			//}

			//validateProperties = (from ia in listItemAttribute
			//                      where ia.Order > 0.0
			//                      orderby ia.Order
			//                      select ia.Name).ToList();
		}

		/// <summary>
		/// Determines whether this instance is valid.
		/// Properties of this instance (child and base class) will be verified.
		/// </summary>
		/// <param name="validateBase">if set to <c>true</c> validate base values.</param>
		/// <returns>
		///   <c>true</c> if this instance is valid; otherwise, <c>false</c>.
		/// </returns>
		public bool IsValid
		{
			get
			{
				this.FillValidateProperties();
				if (validateProperties == null)
				{
					return true;
				}
				else
				{
					return !validateProperties.Any(prop => !string.IsNullOrEmpty(this[prop]));
				}
			}
		}

		#endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        //#region IFocusMover Members

        //public event EventHandler<MoveFocusEventArgs> MoveFocus;

        //public void RaiseMoveFocus(string focusedProperty)
        //{
        //    if (this.MoveFocus != null)
        //    {
        //        this.MoveFocus(this, new MoveFocusEventArgs(focusedProperty));
        //    }
        //}

        //#endregion

        string _name;
        public virtual string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                RaisePropertyChanged("Name");
            }
        }

        int _id;
        public virtual int ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
                RaisePropertyChanged("ID");
            }
        }

        public bool IsNew
        {
            get
            {
                return string.IsNullOrEmpty(Name) || ID == 0;
            }
        }
                
    }
}
